package designPatterns.com.course_design.scrapy;

import designPatterns.com.course_design.scrapy.http.request.Request;
import designPatterns.com.course_design.scrapy.http.response.Response;
import designPatterns.com.course_design.scrapy.http.response.ScrapyResponse;
import designPatterns.com.course_design.scrapy.logger.Log;
import designPatterns.com.course_design.scrapy.util.LogInjection;

import java.util.Date;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import static designPatterns.com.course_design.scrapy.util.ThreadSleep.sleepSeconds;

/**
 * @projectName DesignPattern
 * @className study.scrapy.Downloader
 * @description
 */

/**
 * 运行状态划分
 * 1.队列为空，且正在运行         true
 * 2.正在等待  队列不为空        true
 * 3.队列为空，且正在等待         false
 * 4.队列不为空，但误入了等待状态  true
 */


public final class DownLoader extends ReentrantLock implements Runnable {
    private Engine engine;
    private final Queue<Request> requests = new LinkedBlockingDeque<>();
    @LogInjection
    private Log log;

    protected float delay = 0.5f;
    private final Condition condition = this.newCondition();

    public void signalCondition(){
        this.condition.signalAll();
    }
    public void addRequest(Request request) {
        requests.add(request);
    }
    public boolean isEmpty(){return requests.isEmpty();}
    public  boolean signal() {
        this.lock();
        boolean flag = !(this.getWaitQueueLength(condition) > 0 && this.requests.isEmpty());
        this.unlock();
        return flag;
    }

    @Override
    public void run() {
        while (this.engine.isRunning()) {
            this.lock();
            try {
                while (this.requests.isEmpty() && this.engine.isRunning()){ //如果队列没有请求，则进入等待状态
                    condition.await();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }finally {
                //被唤醒则解锁
                this.unlock();
            }
            //如果引擎关闭则退出，结束线程
            if (engine.getCurrentState() == Engine.END)
                break;
            Request request = requests.poll();
            log.info("开始下载网页:" + request.getUrl());
            //下载过程 TODO
            //...........................
            log.info("成功下载网页:" + request.getUrl());
            Response response = new ScrapyResponse();
            response.setUrl(request.getUrl());
            response.setBody(new Date().toString());
            log.info("downloader 回传response给engine,url:" + request.getUrl());
            //交给引擎
            engine.getResponseFromDownLoader(response);
            //请求之间加上一个延迟，不会因为太频繁而被封IP
            sleepSeconds(delay);
        }
        System.out.println("=====================END OF DOWNLOADER====================");
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}

//    public  Condition getCondition() {
//        return this.condition;
//    }

/**
 //     * 队列不为空且正在等待，应该退出
 //     * @return
 //     */
//    public boolean errorWait(){
//        this.lock();
//        boolean flag = this.getWaitQueueLength(condition) > 0 && !this.requests.isEmpty();
//        this.unlock();
//        return flag;
//    }